﻿using Dokan;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Linq;
using System.ServiceModel;
using System.ServiceProcess;
using System.Text;
using System.Threading.Tasks;

namespace Organizer.Server
{
    public partial class Service : ServiceBase
    {
        private static readonly log4net.ILog log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);

        public ServiceHost serviceHost = null;

        public Service()
        {
            log.Trace(System.Reflection.MethodBase.GetCurrentMethod().Name + " called");

            InitializeComponent();
        }

        // Start Windows Service
        protected override void OnStart(string[] args)
        {
            log.Trace(System.Reflection.MethodBase.GetCurrentMethod().Name + " called");

            // Start Server Host
            StartServiceHost();

            // Start File System
            StartFileSystem();
        }

        protected override void OnStop()
        {
            log.Trace(System.Reflection.MethodBase.GetCurrentMethod().Name + " called");

            // Stop Service Host
            StopServiceHost();

            // Stop File System
            StopFileSystem();
        }

        #region ServiceHost
        private void StartServiceHost()
        {
            log.Trace(System.Reflection.MethodBase.GetCurrentMethod().Name + " called");

            if (serviceHost != null)
            {
                serviceHost.Close();
            }

            // Create a ServiceHost for the WebService type and provide the base address.
            serviceHost = new ServiceHost(typeof(IWebService));

            // Open the ServiceHostBase to create listeners and start listening for messages.
            serviceHost.Open();
        }

        private void StopServiceHost()
        {
            log.Trace(System.Reflection.MethodBase.GetCurrentMethod().Name + " called");

            if (serviceHost != null)
            {
                serviceHost.Close();
                serviceHost = null;
            }
        }
        #endregion // ServiceHost

        #region FileSystem
        public void StartFileSystem()
        {
            log.Trace(System.Reflection.MethodBase.GetCurrentMethod().Name + " called");

            DokanOptions opt = new DokanOptions();
            opt.MountPoint = "r:\\";
            opt.DebugMode = true;
            opt.UseStdErr = true;
            opt.ThreadCount = 5;
            opt.VolumeLabel = "Wichu's Media Organizer";

            int status = DokanNet.DokanMain(opt, new FileSystem());
            switch (status)
            {
                case DokanNet.DOKAN_DRIVE_LETTER_ERROR:
                    log.Error("Drive Letter Error");
                    break;
                case DokanNet.DOKAN_DRIVER_INSTALL_ERROR:
                    log.Error("Driver Install Error");
                    break;
                case DokanNet.DOKAN_MOUNT_ERROR:
                    log.Error("Mount Error");
                    break;
                case DokanNet.DOKAN_START_ERROR:
                    log.Error("Start Error");
                    break;
                case DokanNet.DOKAN_ERROR:
                    log.Error("Unknown Error");
                    break;
                case DokanNet.DOKAN_SUCCESS:
                    log.Debug("Success");
                    break;
                default:
                    log.Warn("Unknown Status: "+ status);
                    break;
            }
        }

        public void StopFileSystem()
        {
            log.Trace(System.Reflection.MethodBase.GetCurrentMethod().Name + " called");

            DokanNet.DokanUnmount('r');
        }
        #endregion // FileSystem
    }
}